package mapData;
import java.util.ArrayList;



import gui.GamePanel;

public class Coord implements Comparable<Coord>
{
    protected int x, y;
    public Coord parent; //parent Coord for use with pathfinding
    public int costSoFar = 0;
    public int centerVal = 0; //used if generated as estimated center
    	//contains units in block
    
    public Coord()
    {
        x = 0;
        y = 0;
    }
    public Coord(int xC, int yC)
    {
        x = xC;
        y = yC;
    }
    
    public Coord(Coord c)
    {
    	x = c.getX();
    	y = c.getY();
    }
    
    public int compareTo(Coord o)
    {
        int oX = o.getX();
        int oY = o.getY();
        if(y < oY || (y == oY && x < oX))
            return -1;
        else if(isEqual(o))
            return 0;
        else 
            return 1;
    }
    
    
    public int getX()
    {
        return x;
    }
    
    public int getY()
    {
        return y;
    }
    
    public void setX(int xC)
    {
        x = xC;
    }
    
    public void setY(int yC)
    {
        y = yC;
    }
    
    public boolean isEqual(Coord comp)
    {
        if( x == comp.getX() && y == comp.getY())
        {
            return true;
        }
        return false;
    }
    
    public String toString()
    {
        String xStr = x + "";
        String yStr = y + "";
        return new String("("+ xStr +","+yStr+")");
    }
    
    public boolean isValid() //returns true if within map bounds
    {
        if(x>=0 && y>=0 && x<Map.width && y < Map.height)
            return true;
        else
            return false;
    }
    
    public boolean isWithinSameCluster(Coord compare)
    {
    	int partitionWidth = GamePanel.aMap.getClusterWidth();
    	int partitionHeight = GamePanel.aMap.getClusterHeight();
    	if(compare.x/partitionWidth == this.x/partitionWidth 
    			&& compare.y/partitionHeight == this.y/partitionHeight)
    	{
    		return true;
    	}
    	else
    	{
    		return false;
    	}
    }
    
    
    /**
     * searches adjacent Coords for unobstructed but potentially occupied positions  
     * @return An ArrayList of Coords
     */
    public ArrayList<Coord> getUnobstructedNeighbors()
    {
    	Coord xy = this;
    	int x = xy.getX();
        int y = xy.getY();
        ArrayList<Coord> nbrs = new ArrayList<Coord>(4);
        Coord north = new Coord(x, y-1);
        Coord south = new Coord(x, y+1);
        Coord east = new Coord(x+1, y);
        Coord west = new Coord(x-1, y);
        
        north.parent = xy;
        south.parent = xy;
        east.parent = xy;
        west.parent = xy;
        
        if(north.isValid() && !GamePanel.pfinder.isOnObstruction(north))
        {
            nbrs.add(north);
        }
        if(east.isValid() && !GamePanel.pfinder.isOnObstruction(east))
        {
            nbrs.add(east);
        }
        
        if(south.isValid() && !GamePanel.pfinder.isOnObstruction(south))
        {
            nbrs.add(south);
        }
        if(west.isValid() && !GamePanel.pfinder.isOnObstruction(west))
        {
            nbrs.add(west);
        }
        return nbrs;
    }
    
    public ArrayList<Coord> getEmptyNeighbors()
    // returns up to 4 unoccupied neighbors in 4 cardinal directions
	{
    	Coord xy = this;
	    int x = xy.getX();
	    int y = xy.getY();
	    ArrayList<Coord> nbrs = new ArrayList<Coord>();
	    Coord north = new Coord(x, y-1);
	    Coord south = new Coord(x, y+1);
	    Coord east = new Coord(x+1, y);
	    Coord west = new Coord(x-1, y);
	    
	    int cost = xy.costSoFar;
	    	    
	    north.parent = xy;
	    north.costSoFar = cost++;
	    south.parent = xy;
	    south.costSoFar = cost++;
	    east.parent = xy;
	    east.costSoFar = cost++;
	    west.parent = xy;
	    west.costSoFar = cost++;
	    
	    
	    
	    if(GamePanel.pfinder.isEmpty(north) && north.isValid())
	    {
	        nbrs.add(north);
	    }
	    if(GamePanel.pfinder.isEmpty(east) && east.isValid())
	    {
	        nbrs.add(east);
	    }
	    
	    if(GamePanel.pfinder.isEmpty(south) && south.isValid())
	    {
	        nbrs.add(south);
	    }
	    if(GamePanel.pfinder.isEmpty(west) && west.isValid())
	    {
	        nbrs.add(west);
	    }
	    return nbrs;
	    
	}
    
    public ArrayList<Coord> getEmptyNeighborsWithClusterLimitation()
    // returns up to 4 unoccupied neighbors in 4 cardinal directions
	{
    	Coord xy = this;
	    int x = xy.getX();
	    int y = xy.getY();
	    ArrayList<Coord> nbrs = new ArrayList<Coord>(4);
	    Coord north = new Coord(x, y-1);
	    Coord south = new Coord(x, y+1);
	    Coord east = new Coord(x+1, y);
	    Coord west = new Coord(x-1, y);
	    
	    north.parent = xy;
	    south.parent = xy;
	    east.parent = xy;
	    west.parent = xy;
	    
	    if(GamePanel.pfinder.isEmpty(north) && north.isValid() && isWithinSameCluster(north))
	    {
	        nbrs.add(north);
	    }
	    if(GamePanel.pfinder.isEmpty(east) && east.isValid() && isWithinSameCluster(east))
	    {
	        nbrs.add(east);
	    }
	    
	    if(GamePanel.pfinder.isEmpty(south) && south.isValid() && isWithinSameCluster(south))
	    {
	        nbrs.add(south);
	    }
	    if(GamePanel.pfinder.isEmpty(west) && west.isValid() && isWithinSameCluster(west))
	    {
	        nbrs.add(west);
	    }
	    return nbrs;
	    
	}
    
}
